The color-scheme CSS property and the corresponding meta tagallow developers to opt their pages in to the theme-specific defaults of the user agent stylesheet.
Thomas SteinerX GitHub Glitch LinkedIn Mastodon HomepageBackgroundThe prefers-color-scheme user preference media featureTheprefers-color-schemeuser preference media feature gives developers full control over their pages' appearances.If you are unfamiliar with it, please read my articleprefers-color-scheme: Hello darkness, my old friend,where I documented everything I know about creating amazing dark mode experiences.
One puzzle piece that was only mentioned briefly in the article isthe color-scheme CSS property and the corresponding meta tag of the same name.They both make your life as a developer easierby allowing you to opt your page in to theme-specific defaults of the user agent stylesheet,such as, for example, form controls, scroll bars, as well as CSS system colors.At the same time, this feature prevents browsers from applying any transformations on their own.
Browser supportprefers-color-scheme
Browser Support
76 79 67 12.1Source
color-scheme
Browser Support
81 81 96 13Source
The user agent stylesheetBefore I continue, let me briefly describe what a user agent stylesheet is.Most of the time, you can think of the word user agent (UA)as a fancy way to say browser.The UA stylesheet determines the default look and feel of a page.As the name suggests, a UA stylesheet is something that depends on the UA in question.You can have a look atChrome's(and Chromium's) UA stylesheet and compare it toFirefox's orSafari's (and WebKit's).Typically, UA stylesheets agree on the majority of things.For example, they all make links blue, general text black, and background color white,but there are also important (and sometimes annoying) differences,for instance, how they style form controls.
Have a closer look atWebKit's UA stylesheetand what it does regarding dark mode.(Do a full text search for "dark" in the stylesheet.)The default provided by the stylesheet changes based on whether dark mode is on or off.To illustrate this, here is one such CSS rule using the:matchespseudo class and WebKit-internal variables like -apple-system-control-background,as well as the WebKit-internal preprocessor directive #if defined:
input,input:matches([type="password"], [type="search"]) { -webkit-appearance: textfield; #if defined(HAVE_OS_DARK_MODE_SUPPORT) && HAVE_OS_DARK_MODE_SUPPORTcolor: text;background-color: -apple-system-control-background; #elsebackground-color: white; #endif /* snip */}You will notice some non-standard values for the color and background-color properties above.Neither text nor -apple-system-control-background are valid CSS colors.They are WebKit-internal semantic colors.
Turns out, CSS has standardized semantic system colors.They are specified inCSS Color Module Level 4.For example,Canvas(not to be confused with the tag)is for the background of application content or documents,whereasCanvasTextis for text in application content or documents.The two go together and should not be used in isolation.
UA stylesheets can use either their own proprietary or the standardized semantic system colors,to determine how HTML elements should be rendered by default.If the operating system is set to dark mode or uses a dark theme,CanvasText (or text) would be conditionally set to white,and Canvas (or -apple-system-control-background) would be set to black.The UA stylesheet then assigns the following CSS only once, and covers both light and dark mode.
/** Not actual UA stylesheet code. For illustrative purposes only.*/body { color: CanvasText; background-color: Canvas}The color-scheme CSS propertyThe CSS Color Adjustment Module Level 1specification introduces a model and controlsover automatic color adjustment by the user agentwith the objective of handling user preferencessuch as dark mode, contrast adjustment, or specific desired color schemes.
The color-schemeproperty defined therein allows an element to indicatewhich color schemes it is comfortable being rendered with.These values are negotiated with the user's preferences, resulting in a chosen color schemethat affects user interface (UI) things such as the default colors of form controlsand scroll bars, as well as the used values of the CSS system colors.The following values are currently supported:
normal Indicates that the element is not aware of color schemes at all,and so the element should be rendered with the browser's default color scheme.
[ light | dark ]+ Indicates that the element is aware of and can handlethe listed color schemes, and expresses an ordered preference between them.
Note: Providing both keywords indicates that the first scheme is preferred (by the author), but the second is also acceptable if the user prefers it instead.In this list, light represents a light color scheme,with light background colors and dark foreground colors,whereas dark represents the opposite, with dark background colors and light foreground colors.
For all elements, rendering with a color scheme should cause the colors usedin all browser-provided UI for the element to match with the intent of the color scheme.Examples are scroll bars, spellcheck underlines, form controls, etc.
Note: The color-scheme CSS property can be used on both the :root level, as well as on an individual per-element level.On the :root element, rendering with a color schemeadditionally must affect the surface color of the canvas (that is, the global background color),the initial value of the color property, and the used values of the system colors,and should also affect the viewport's scroll bars.
/* The page supports both dark and light color schemes, and the page author prefers dark.*/:root { color-scheme: dark light;}The color-scheme meta tagHonoring the color-scheme CSS property requires the CSS to be first downloaded(if it is referenced via ) and to be parsed.To aid user agents in rendering the page background with the desired color scheme immediately,a color-scheme value can also be provided in aelement.
Combining color-scheme and prefers-color-schemeSince both the meta tag and the CSS property (if applied to the :root element)eventually result in the same behavior, I always recommend specifying the color schemevia the meta tag, so the browser can adopt to the preferred scheme faster.
While for absolute baseline pages no additional CSS rules are necessary,in the general case you should always combine color-scheme with prefers-color-scheme.For example, the proprietary WebKit CSS color -webkit-link, used by WebKit and Chromefor the classic link blue rgb(0,0,238),has an insufficient contrast ratio of 2.23:1 on a black background andfailsboth the WCAG AA as well as the WCAG AAArequirements.
I have opened bugs for Chrome,WebKit, andFirefoxas well as a meta issue in the HTML Standardto get this fixed.
Interplay with prefers-color-schemeThe interplay of the color-scheme CSS property and the corresponding meta tagwith the prefers-color-scheme user preference media feature may seem confusing at first.In fact, they play together really well.The most important thing to understand is that color-schemeexclusively determines the default appearance,whereas prefers-color-scheme determines the stylable appearance.To make this clearer, assume the following page:
fieldset { background-color: gainsboro;}@media (prefers-color-scheme: dark) { fieldset {background-color: darkslategray; }}Lorem ipsum dolor sit amet, legere ancillae ne vis.
Lorem ipsum Lorem ipsumThe inline CSS code on the pagesets the element's background-color to gainsboro in the general case,and to darkslategray if the user prefers a dark color schemeaccording to the prefers-color-scheme user preference media feature.
Via the element,the page tells the browser that it supports a dark and a light theme,with a preference for a dark theme.
Depending on whether the operating system is set to dark or light mode,the whole page appears light on dark, or vice versa, based on the user agent stylesheet.There is no additional developer-provided CSS involved to change the paragraph textor the background color of the page.
Note how the element's background-color changesbased on whether dark mode is enabled, following the rulesin the developer-provided inline stylesheet on the page.It is either gainsboro or darkslategray.
Light mode: Styles specified by the developer and the user agent.The text is black and the background is white as per the user agent stylesheet.The element's background-color is gainsboroas per the inlined developer stylesheet. Dark mode: Styles specified by the developer and the user agent.The text is white and the background is black as per the user agent stylesheet.The element's background-color is darkslategrayas per the inlined developer stylesheet.The element's appearance is controlled by the user agent stylesheet.Its color is set to theButtonTextsystem color, and its background-color and the four border-colors are set to the system colorButtonFace.
Light mode: The background-color and the variousborder-colors are set to the ButtonFacesystem color.Now note how the element's border-color changes.The computed value for the border-top-color and the border-bottom-colorswitches from rgba(0, 0, 0, 0.847) (blackish) to rgba(255, 255, 255, 0.847) (whitish),since the user agent updates ButtonFace dynamically based on the color scheme.The same applies for the element's colorthat is set to the corresponding system color ButtonText.
Light mode: The computed values of the border-top-colorand the border-bottom-color that are both set to ButtonFacein the user agent stylesheet are now rgba(0, 0, 0, 0.847). Dark mode: The computed values of the border-top-colorand the border-bottom-color that are both set to ButtonFacein the user agent stylesheet are now rgba(255, 255, 255, 0.847). DemoYou can see the effects of color-scheme applied to a large number of HTML elementsin a demo on Glitch.The demo deliberately shows the WCAG AA and WCAG AAAviolationwith the link colors mentioned in the warning above.
The demotoggled to color-scheme: light. The demotoggled to color-scheme: dark.Note the WCAG AA and WCAG AAA violationwith the link colors. AcknowledgementsThe color-scheme CSS property and the corresponding meta tag were implemented byRune Lillesveen.Rune is also a co-editor of the CSS Color Adjustment Module Level 1 specification.Hero image byPhilippe Leoneon Unsplash.